package com.itheima.service.impl;

import com.itheima.common.utils.DateUtils;
import com.itheima.mapper.MemberDao;
import com.itheima.mapper.OrderDao;
import com.itheima.mapper.SetmealDao;
import com.itheima.pojo.*;
import com.itheima.service.ReportService;
import lombok.Data;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

@Service
public class ReportServiceimpl implements ReportService {

    @Autowired
    SetmealDao setmealDao;
    @Autowired
    MemberDao memberDao;

    @Autowired
    OrderDao orderDao;


    @Override
    public SetmealVO getSeymealReport() {

        List<String> setmealNames = setmealDao.getSetmealNames();
        List<SetmealCount> setmealCounts = new ArrayList<>();
        for(String name : setmealNames) {

            SetmealCount setmealCount = setmealDao.getSetmealCountByName(name);
            if(setmealCount == null){
                continue;
            }
            setmealCounts.add(setmealCount);


        }
        SetmealVO setmealVO = new SetmealVO();
        setmealVO.setSetmealNames(setmealNames);
        setmealVO.setSetmealCount(setmealCounts);
        return setmealVO;
    }

    @Override
    public MemberVO getMemberReport() {


//        获取当前年月
        LocalDate now = LocalDate.now();
        String endyearAndMonth = now.getYear() + "-" + now.getMonthValue();
        String startyearAndMonth = (now.getYear() - 1) + "-" + now.getMonthValue();


        List<String> months;
        try {
            months = DateUtils.getMonthBetween(startyearAndMonth, endyearAndMonth, "yyyy.MM");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        List<String> months1;
        try {
            months1 = DateUtils.getMonthBetween(startyearAndMonth, endyearAndMonth, "yyyy-MM");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        List<Integer> memberCounts = new ArrayList<>();
        for (String month1 : months1) {
            // 获取每个月的会员数量
            Integer count = memberDao.getMemberCountByMonth(month1);
            // 这里可以将count存储到某个数据结构中，例如List或Map，以便后续使用
            memberCounts.add(count);
        }
        MemberVO memberVO = new MemberVO();
        memberVO.setMonths(months);
        memberVO.setMemberCount(memberCounts);
        return memberVO;

    }

    @Override
    public BusinessReportDataVO getBusinessReportData() {

        BusinessReportDataVO businessReportDataVO = new BusinessReportDataVO();
        String reportData = LocalDate.now().toString();
//        获取当天日期
        businessReportDataVO.setReportDate(reportData);
//        获取当天到诊人数
        String OrderStatus = Order.ORDERSTATUS_YES;
        Integer todayVisitsNumber = orderDao.findMemberCountByDate(reportData,OrderStatus);
        businessReportDataVO.setTodayVisitsNumber(todayVisitsNumber);
//        获取当天新增会员数
        Integer todayNewMember = memberDao.findNewMemberCountByDate(reportData);
        businessReportDataVO.setTodayNewMember(todayNewMember);
//        获取这周到诊人数

        Date start = DateUtils.getThisWeekMonday();
        Date end = DateUtils.getSundayOfThisWeek();
        Integer thisWeekVisitsNumber = orderDao.findVisitsNumberCountByWeek(start,end,OrderStatus);
        businessReportDataVO.setThisWeekVisitsNumber(thisWeekVisitsNumber);

//        获取本月新增会员数
        String reportMonth = LocalDate.now().getYear() + "-" + LocalDate.now().getMonthValue();

        Integer thisMonthNewMember = memberDao.getMemberCountByMonth(reportMonth);
        businessReportDataVO.setThisMonthNewMember(thisMonthNewMember);

//        获取本周新增会员数
        Integer thisWeekNewMember = memberDao.getMemberCountByWeek(start,end);
        businessReportDataVO.setThisWeekNewMember(thisWeekNewMember);
//        获取总会员数
        Integer totalMember = memberDao.getTotalMember();
        businessReportDataVO.setTotalMember(totalMember);

//        获取本月预约人数
        Integer thisMonthOrderNumber = orderDao.getMemberCountByMonth(reportMonth);
        businessReportDataVO.setThisMonthOrderNumber(thisMonthOrderNumber);
//        获取本月到诊人数
        Integer thisMonthVisitsNumber = orderDao.getMonthVisistsCountByMonth(reportMonth,OrderStatus);
        businessReportDataVO.setThisMonthVisitsNumber(thisMonthVisitsNumber);

//        获取当天预约人数
        Integer todayOrderNumber = orderDao.findCountByDate(reportData);
        businessReportDataVO.setTodayOrderNumber(todayOrderNumber);

//        获取本周预约人数
        Integer thisWeekOrderNumber = orderDao.findOrderCountByWeek(start,end);
        businessReportDataVO.setThisWeekOrderNumber(thisWeekOrderNumber);


//        查询本月热门套餐
        List<String> nameList= orderDao.findName();
        List<HotSetmeal> hotSetmeals = new ArrayList<>();
        for(String name : nameList){

            HotSetmeal hotSetmeal = new HotSetmeal();
            Integer setmealCount = orderDao.findCountByName(name);
            hotSetmeal.setName(name);
            hotSetmeal.setSetmeal_count(setmealCount);
            double proportion = setmealCount.doubleValue()/orderDao.findCount() ;
            hotSetmeal.setProportion(proportion);
            hotSetmeals.add(hotSetmeal);
        }
//        将hostSetmeal按setmeal_count从大到小的顺序排列
        hotSetmeals.sort((o1, o2) -> o2.getSetmeal_count().compareTo(o1.getSetmeal_count()));
        List<HotSetmeal> hotSetmeals1 = new ArrayList<>();
        for(int i=0;i<4;i++){
            hotSetmeals1.add(hotSetmeals.get(i));
        }

        businessReportDataVO.setHotSetmeal(hotSetmeals1);


        return businessReportDataVO;

    }

    @Override
    public void exportBusinessReport(HttpServletResponse response) {


        BusinessReportDataVO businessDataVO = getBusinessReportData();
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");

        try {
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=report_template.xlsx");


            XSSFWorkbook excel = new XSSFWorkbook(in);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(2).getCell(5).setCellValue(businessDataVO.getReportDate());
            XSSFRow row = sheet.getRow(4);
            row.getCell(5).setCellValue(businessDataVO.getTodayVisitsNumber());
            row.getCell(7).setCellValue(businessDataVO.getTotalMember());
            row = sheet.getRow(5);
            row.getCell(5).setCellValue(businessDataVO.getThisWeekNewMember() );
            row.getCell(7).setCellValue(businessDataVO.getThisMonthNewMember());
            row = sheet.getRow(7);
            row.getCell(5).setCellValue(businessDataVO.getTodayOrderNumber());
            row.getCell(7).setCellValue(businessDataVO.getTodayVisitsNumber());
            row = sheet.getRow(8);
            row.getCell(5).setCellValue(businessDataVO.getThisWeekOrderNumber());
            row.getCell(7).setCellValue(businessDataVO.getThisWeekVisitsNumber());
            row = sheet.getRow(9);
            row.getCell(5).setCellValue(businessDataVO.getThisMonthOrderNumber());
            row.getCell(7).setCellValue(businessDataVO.getThisMonthVisitsNumber());
            for(int i=0;i<businessDataVO.getHotSetmeal().size();i++){
                HotSetmeal hotSetmeal = businessDataVO.getHotSetmeal().get(i);
                XSSFRow row1 = sheet.getRow(12+i);
                row1.getCell(4).setCellValue(hotSetmeal.getName());
                row1.getCell(5).setCellValue(hotSetmeal.getSetmeal_count());
                row1.getCell(6).setCellValue(hotSetmeal.getProportion());
            }

            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            out.close();
            in.close();
            excel.close();


        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }

    }



}
